package com.spark.market.service.impl;

import com.spark.market.api.dto.ItemInfo;
import com.spark.market.api.mq.ItemStockMqMessage;
import com.spark.market.api.request.ItemAddParam;
import com.spark.market.api.request.ItemDecreaseParam;
import com.spark.market.api.result.ItemStockDecreaseResult;
import com.spark.market.common.exception.BusinessException;
import com.spark.market.common.exception.EmBusinessError;
import com.spark.market.common.utils.AssertUtils;
import com.spark.market.dal.model.ItemModel;
import com.spark.market.service.ItemCmdCoreService;
import com.spark.market.service.manager.ItemManager;
import com.spark.market.service.manager.mq.producer.ItemStockProducerManager;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class ItemCmdCoreServiceImpl implements ItemCmdCoreService {
    @Resource
    private ItemManager itemManager;

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    @Resource
    private ItemStockProducerManager itemStockProducerManager;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ItemInfo createItem(ItemAddParam param) {
        AssertUtils.isNotNull(param, "ItemInfo is null");
        //保存商品项
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(param, itemModel);
        itemModel.setPrice(param.getPrice());
        return itemManager.createItem(itemModel);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ItemStockDecreaseResult decreaseItemStock(ItemDecreaseParam param) {
        AssertUtils.isNotNull(param, "ItemDecreaseParam is null");
        boolean res = itemManager.decreaseStock(param.getItemId(), param.getAmount());
        ItemStockDecreaseResult itemStockDecreaseResult = new ItemStockDecreaseResult();
        itemStockDecreaseResult.setStatus(res);
        return itemStockDecreaseResult;
    }

    @Override
    public ItemStockDecreaseResult decreaseItemStockByCache(ItemDecreaseParam param) {
        //校验库存是否售空
        if (redisTemplate.hasKey("promo_item_stock_invalid_" + param.getItemId())) {
            throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
        }
        long result = redisTemplate.opsForValue().increment("promo_item_stock_" + param.getItemId(), param.getAmount() * -1);
        ItemStockDecreaseResult itemStockDecreaseResult = new ItemStockDecreaseResult();
        if (result > 0) {
            itemStockDecreaseResult.setStatus(true);
        } else if (result == 0) {
            //通知库存售完
            redisTemplate.opsForValue().set("promo_item_stock_invalid_" + param.getItemId(), "true");
        } else {
            itemStockDecreaseResult.setStatus(false);
        }
        return itemStockDecreaseResult;
    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void increaseSales(Integer itemId, Integer amount) {
        AssertUtils.isNotNull(itemId, "itemId is null");
        AssertUtils.isNotNull(amount, "amount is null");
        itemManager.increaseSales(itemId, amount);
    }

    @Override
    public void syncDecreaseItemStockByMq(ItemStockMqMessage itemStockMqMessage) {
        itemStockProducerManager.sendItemStockMsg(itemStockMqMessage);
    }

}
